L20: Git

linux.edumach.cz



1. Typy verzovacích systémů

VCS -- Version Control System

  1. Lokální – všichni musí využívat jeden sdílený filesystem.
  2. Klient-server – všichni používají jeden centrální repozitář (SVN, CVS).
  3. Distribuované – každý používá svůj lokální repozitář a změny jsou sdíleny přes vzdálený repozitář.

2. Git

3. Kontrola gitu

Kontrola, zda na je na počítači git nainstalovaný se provede příkazem:

$ git --version
git version 2.39.5

Číslo verze je pouze orientační. Pro samotnou funkci nemá vliv.

4. Základní nastavení gitu

Příkazem git config -list si vypíšete kompletní současné nastavení.

Pro fungování vyžaduje git minimálně jméno a e-mail:

git config --global user.name "Jméno Příjmení"  
git config --global user.email jmeno@email.cz  

Výpis údajů (pro kontrolu):

machac@TuX  ~
$ git config user.name
Jiří Machač

machac@TuX  ~
$ git config user.email
machac@panska.cz

Nebo také:

$ git config --global --list
$ git config --global -l

5. Založení git repozitáře

K tomu stačí vytvořit složku a v ní inicializovat git repozitář (příkazem git init).

cd 
mkdir git-pokus 
cd git-pokus 
git status 
git init 
git status 

Výstupem bude něco takového:

mkdir git-pokus -- Vytvoření nové složky s názvem git-pokus.

cd git-pokus -- Přesun do nově vytvořené složky git-pokus.

git status -- Zobrazení stavu repozitáře Git (zatím žádný repozitář neexistuje, takže zobrazí chybovou hlášku):

fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

git init -- Inicializace nového prázdného Git repozitáře v aktuální složce (toto se provádí jen jednou). Ve složce s projektem si git vytvořil skrytou složku .git. Do ní si git bude vše zaznamenávat:

Initialized empty Git repository in /home/machac/git-pokus/.git/

git status -- Opětovné zobrazení stavu repozitáře, nyní již inicializovaného (repozitář existuje, ale neobsahuje žádné soubory ke sledování):

On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)

5.1. Shrnutí

  1. Veškeré změny si git zapisuje do skryté složky .git. Celý projekt je samonosný a přenositelný. Není svázaný s konkrétním místem nebo počítačem. Git nevyžaduje server. Složku s projektem si můžete klidně přenést např. na USB disk a pracovat kdekoliv jinde. Stačí tam mít git nainstalovaný a nastavené své jméno a e-mail.

  2. Důležitým příkazem je git status. Pomocí něho kdykoliv zjistíte, v jakém stavu se repozitář nachází. Toto je nesmírně důležité. Postupně si to ukážeme.

6. Pracovní oblasti

Specialitou Gitu jsou tři oblasti – ne dvě jako u jiných verzovacích systémů.

Git používá Staging Area. Tu si můžeme představit jako nástupiště na nádraží:

Ne každý člověk (soubor) stojící na nástupišti musí vlakem odjet. Někteří mohou zůstat stát a počkat na další spoj (další commit). A když se člověk převlékne (soubor se znovu změní), musí znovu projít turniketem a přijít na nástupiště (opět git add).

Výsledkem je, že v commitu jsou přesně ti cestující (verze souborů), které jsme na nástupiště pustili – a jen ti odjedou vlakem do historie.

Pracovní adresář
(repozitář)
Staging Area Revize
(commity)
ovoce.txt
zelenina.txt
ovoce.txt
f19a959 \leftarrow HEAD
8e3111c
b88b254
b593444
cdd927c
9518e20

Je čas si verzování vyzkoušet v praxi.

Ve složce s projektem vytvoř soubory ovoce.txt a zelenina.txt:

machac@TuX  ~/git-pokus (master #)
$ touch ovoce.txt zelenina.txt

machac@TuX  ~/git-pokus (master #)
$ ls
ovoce.txt  zelenina.txt

Příkazem git status zjisti stav repozitáře:

Příkazem git add ovoce.txt přidej soubor ovoce.txt do Staging Area (aby jej git začal sledovat):

Nyní vytvořte commit příkazem

git commit -m "Vytvořen soubor ovoce.txt"

Edituj soubor ovoce.txt a přidej do něj text:

Lesní ovoce 
=========== 
Maliny 
Ostružiny 

Opět zjisti stav repozitáře příkazem git status:

Tentokrát přidej do Staging Area všechny (tedy oba dva) soubory. K tomu slouží příkaz git add . (tečka). Avšak lepší a doporučovaný je git add -A. Oproti předchozímu sleduje i smazané soubory, což se může někdy hodit. Pak následuje opět commit s vhodným komentářem. V terminálu jde oba příkazy sloučit dvojicí &&:

git add -A && git commit -m "přidané všechny soubory"

Poznámka:
Pozorný žák si zajisté všiml, že git v předchozím příkazu doporučil i příkaz git commit -a. Ten provede commit všech změněných a smazaných souborů, aniž by bylo nutné je nejprve přidávat pomocí git add. Ale pozor:

Pokud tedy chceš commitovat i nové soubory, použij nejdříve git add -A.

Repozitář je aktuální a neobsahuje žádné necommitnuté změny. Pokud chceš pokračovat v práci, stačí vytvořit nové změny a přidat je do Staging Area (git add -A) před commitováním (git commit -m "komentář").

7. Výpis commitů

Seznam všech commitů vypíše příkaz git log:

Každý commit je identifikovaný unikátním 40znakovým "commit-hashem". Dále obsahuje údaje o autorovi, časové razítko a komentář.

Co znamená (HEAD -> master):

7.1. Zkrácená verze logu

Pokud je commitů víc, stává se výpis nepřehledným. Příkaz git log --oneline vypíše jen prvních 7 znaků "commit-hashe" a komentář:

Bylo ověřeno, že k jednoznačné identifikaci commitu stačí právě prvních 7 znaků.

8. Aliasy

Pro zjednodušení a zrychlení práce je vhodné si vytvořit "aliasy", např.:

$ git config --global alias.st "status"

Použití: git st

Nastavte si další užitečné aliasy:

$ git config --global alias.lo "log --oneline"
$ git config --global alias.ll "log --all --graph --decorate --oneline"

9. Soubor .gitignore

Může nastat požadavek, kdy nechceme commitovat (verzovat) všechny soubory projektu. Git má speciální soubor .gitignore, který slouží k tomu, aby se určité soubory nebo složky ignorovaly při verzování – tedy aby se nezahrnovaly do repozitáře.

To pomáhá udržet repozitář čistý a přehledný. Zabraňuje náhodnému přidání dočasných souborů, například:

Příklad obsahu .gitignore:

# Ignoruje všechny .log soubory
*.log

# Ignoruje složku modules a její obsah
modules/

10. Práce se staršími verzemi

Cestování v čase

Git nám umožňuje cestovat časem v našem kódu, což je jedna z jeho největších výhod. Díky tomu se můžeme kdykoliv vrátit k předchozím verzím projektu, ať už chceme opravit chybu, obnovit i smazaný soubor nebo jednoduše prozkoumat, jak se projekt vyvíjel.

Je to jako mít archiv všech verzí projektu, kdykoliv po ruce. Git vytváří zálohy všech verzí, takže se nemusíme bát o ztrátu dat.

10.1. Dočasný návrat k předchozí verzi

f0d19fb (HEAD -> master) Stránka kontakty - styly
4d13f71 Stránka kontakty
a68fb03 Výchozí verze
$ git checkout <hash>  (např. git checkout 4d13f71)

Přepne do vybraného commitu, změny se neuloží trvale.

Návrat na nejnovější verzi:

$ git checkout master

Přepne zpět na hlavní větev (master).

10.2. Trvalý návrat k předchozí verzi

f0d19fb (HEAD -> master) Stránka kontakty - styly
4d13f71 Stránka kontakty
a68fb03 Výchozí verze
$ git reset --hard <hash>

např. git reset --hard a68fb03

Vrátí se do zadaného commitu a odstraní všechny následné změny. Zruší (ale fyzicky nesmaže) všechny změny po zadaném commitu.

Návrat na nejnovější verzi pomocí historie HEAD:

Pomocí git reflog najděte hash posledního (nejnovějšího) commitu a vraťte se:

$ git reset --hard f0d19fb